<script lang='ts' setup>
import { IFatForm, IFormItem } from '../type';
import { ElForm } from 'element-plus'
import ViewContainer from '../container/fat-form-ceate-container-view.vue'
import { getAliasValue, setAliasValue } from '../hook'

const props = withDefaults(defineProps<{
  modelValue: any; // 表单数据
  formSetting: IFatForm;
  isMobile?: boolean;
}>(), {
  isMobile: false,
})

//tip 需要父组件传入submit方法,插槽中再返回
const emit = defineEmits<{
  (event: 'submit', data: any): void
  (event: 'update:modelValue', data: any): void
}>()

const state = reactive({
  // params: genParams(props.formSetting.formItems)
  params: props.modelValue
})
watch(() => state.params, () => {
  console.log('params-change', state.params);
}, { deep: true })
const layout = ref()

onMounted(() => {
  refreshLayout()
})

const editFormRef = ref()
const edit = reactive({
  form: {} as any,
  rules: {} as any,
  submit: async () => {
    if (!editFormRef.value) return
    await editFormRef.value.validate((validate: boolean, fields: any) => {
      if (validate) {
        try {
          emit('submit', state.params)
        } catch (error) {
        }
      } else {
        ElMessage.error('请正确填写表单')
      }
    })
  }
})

function refreshLayout() {
  layout.value = genLayout(props.formSetting.formItems)
}
function genLayout(items: IFormItem[], pkey?: string, rowIndex?: number) {
  const layoutList: IFormItem[] = []
  items.forEach((item) => {
    const layout = JSON.parse(JSON.stringify(item)) as IFormItem
    if (typeof rowIndex === 'number') {
      layout.formProp = pkey + '.' + rowIndex + "." + layout.key
      layout.rowIndex = rowIndex
    } else if (pkey) {
      layout.formProp = pkey + '.' + layout.key
    } else {
      layout.formProp = layout.key
    }
    // layoutContainer-formProp use the last level of prop
    if (layout.type === "layoutContainer") {
      layout.formProp = pkey
    }
    const path = layout.formProp ? layout.formProp.split('.') : []
    let params = getAliasValue(path, state.params)

    if (item.type === "arrayContainer") {
      const paramsLength = params?.length ?? 0
      const arrayRows = item.rowLength ?? 1
      if (paramsLength < arrayRows) {
        if (!params) {
          params = setAliasValue([], path, state.params)
        }
        for (let i = paramsLength; i < arrayRows; i++) {
          params[i] = setAliasValue({}, path.concat([i]), state.params)
        }
        // params = setAliasValue([{}], path, state.params)s
      }
      // tip 根据参数长度循环推送
      for (let i = 0; i < params.length; i++) {
        layout.rowIndex = i
        layout.children = genLayout(layout.children, layout.key, i)
        const target = JSON.parse(JSON.stringify(layout))
        layoutList.push(target)
      }
    } else if (item.type === "layoutContainer") {
      layout.children = genLayout(item.children, pkey)
      layoutList.push(layout)
    } else {
      if (!params) {
        setAliasValue("", path, state.params)
      }
      layoutList.push(layout)
    }
  })
  return layoutList
}

provide('isMobile', props.isMobile)
provide('formConfig', props.formSetting.formConfig)
provide("formParams", state.params)
provide('refreshLayout', refreshLayout)
</script>

<template>
  <el-form v-if="layout" :model="state.params" ref="editFormRef" :inline="false"
    :label-position="isMobile ? 'top' : formSetting.formConfig.labelPosition" style="height: 100%;">
    <slot></slot>
    <ViewContainer :form-params="state.params" :layout-list="layout!" item-key="id" />
    <slot name="footer" :formSubmit="edit.submit"></slot>
  </el-form>
</template>

<style lang='scss' scoped>
:deep(.el-form-item) {
  margin-top: 0;
  margin-bottom: 18px;
}
</style>